package com.atguigu.srb.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.service.UserInfoService;
import com.atguigu.srb.core.service.WxLoginService;
import com.atguigu.srb.exception.SRBException;
import com.atguigu.srb.result.ResponseEnum;
import com.atguigu.srb.util.HttpUtils;
import com.atguigu.srb.util.JwtUtils;
import com.atguigu.srb.util.SrbAssert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.http.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * ClassName: WxLoginServiceImpl
 * Package: com.atguigu.srb.core.service.impl
 * Description:
 *
 * @Author 刘强
 * @Create 2024/4/21 21:13
 * @Version 1.0
 */
@Service
public class WxLoginServiceImpl implements WxLoginService {
    @Autowired
    private UserInfoService userInfoService;
    @Override
    public String login(HttpSession session) {
        String redirectUri = URLEncoder.encode("http://localhost:8160/api/wx/callback");
        String state = UUID.randomUUID().toString();
        session.setAttribute("loginSessionId",state);
        return "redirect:https://open.weixin.qq.com/connect/qrconnect?" +  // 获取微信登陆二维码的 接口
                "appid=wxed9954c01bb89b47" +     // 公司在微信上认证的id
                "&redirect_uri=" + redirectUri +  // 用户授权后，微信服务器响应的重定向的接口地址，必须和公司在微信中注册的域名相同 -> 这儿是localhost:8160
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=" + state +
                "#wechat_redirect";
    }

    @Override
    public String callBack(String code, String state, HttpSession session, HttpServletRequest request) {

        // 通过code获取accessToken
        // https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

        // https://api.weixin.qq.com/sns/oauth2/access_token?
        // appid=wxed9954c01bb89b47
        // &secret=a7482517235173ddb4083788de60b90e
        // &code=CODE
        // &grant_type=authorization_code
        String  sessionInServer = (String) session.getAttribute("loginSessionId");

        SrbAssert.assertTrue( state != null && sessionInServer != null  && sessionInServer.equals(state),
                ResponseEnum.WEIXIN_CALLBACK_PARAM_ERROR);

        HashMap<String, String> map = new HashMap<>();
        map.put("appid","wxed9954c01bb89b47");
        map.put("secret","a7482517235173ddb4083788de60b90e");
        map.put("code",code);
        map.put("grant_type","authorization_code");
        byte[] bytes = new byte[0];
        Map<String,Object> map1 = null;
        String openId = null;
        try {
            HttpResponse httpResponse = HttpUtils.doGet("https://api.weixin.qq.com", "/sns/oauth2/access_token", "GET",
                    null, map);
            bytes = HttpUtils.readInputStream(httpResponse.getEntity().getContent());
            map1 = JSON.parseObject(new String(bytes), Map.class);
            System.out.println("map1 = " + map1);
            if(map1.get("errcode")!=null){
                throw  new SRBException(map.get("errmsg").toString(),-10);
            }

            // 根据token去获取用户信息，然后再返回用户信息
            String accessToken = map1.get("access_token").toString();
            openId = map1.get("openid").toString();
            map = new HashMap();
            map.put("access_token",accessToken);
            map.put("openId",openId);
            httpResponse = HttpUtils.doGet("https://api.weixin.qq.com", "/sns/userinfo", "GET", null,
                    map);
            bytes = HttpUtils.readInputStream(httpResponse.getEntity().getContent());
        } catch (Exception e) {
            throw new SRBException(ResponseEnum.WEIXIN_CALLBACK_PARAM_ERROR);
        }
        map1 = JSON.parseObject(new String(bytes), Map.class);
        System.out.println("用户信息 = " + map1);
        String nickName = map1.get("nickname").toString();
        String headImgUrl = map1.get("headimgurl").toString();
        // 判断用户是否已经注册
        UserInfo userInfo = userInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getOpenid, openId));
        if(userInfo != null ){
            // 更新用户名和头像即可
            userInfo.setNickName(nickName);
            userInfo.setHeadImg(headImgUrl);
            userInfoService.updateById(userInfo);
            String token = JwtUtils.createToken(userInfo.getId(), userInfo.getNickName());
            // 登陆成功 -> 响应token 并且重定向到首页(微信扫码登录，不是我们前端发送的请求，所以接收不到响应体)
            // 我们想要让显示的界面跳转到首页 并且 加载最新的数据
            //  重定向  +   更新token
            // 原理： 一旦重定向到首页(首页刷新)，就会根据本地缓存的token发送请求来加载用户数据
            userInfoService.saveLoginLogs(request,userInfo,1);
            return "redirect:http://localhost:3000?token=" + token;
        }
        // 用户没有注册，则保存微信用户到数据库
        userInfo = new UserInfo();
        userInfo.setNickName(nickName);
        userInfo.setHeadImg(headImgUrl);
        userInfo.setOpenid(openId);
        userInfo.setIntegral(0);
        userInfo.setSalt("vx");
        userInfoService.save(userInfo); // 插入数据库时，id会由雪花算法自动生成
        String token = JwtUtils.createToken(userInfo.getId(), nickName);
        return "redirect:http://localhost:3000?token=" + token;
    }
}

